package com.zx.token.controller;

import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user/")
@Slf4j
public class UserController {
    
    /**SaToken 做同客户端互斥的时候，使用*/
    public static final String DEVICE_PC="PC";


    @GetMapping("checkLogin")
    public void checkLogin() {
        StpUtil.checkLogin();
    }
    // 测试登录，浏览器访问： http://localhost:8081/user/doLogin?username=zhang&password=123456
    @RequestMapping("doLogin")
    public SaResult doLogin(String username, String password) {
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对 
        if("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001,DEVICE_PC);
            return SaResult.data(StpUtil.getTokenInfo());
        }
        return SaResult.error("登录失败");
    }

    @RequestMapping("appLogin")
    public SaResult doAppLogin(String username, String password) {
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对 
        if("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001,"app");
            return SaResult.data(StpUtil.getTokenInfo());
        }
        return SaResult.error("登录失败");
    }

    // 查询登录状态，浏览器访问： http://localhost:8081/user/isLogin
    @RequestMapping("isLogin")
    public Boolean isLogin() {
        return  StpUtil.isLogin();
    }

    // 查询 Token 信息  ---- http://localhost:8081/acc/tokenInfo
    @GetMapping("tokenInfo")
    public SaResult tokenInfo() {
        return SaResult.data(StpUtil.getTokenInfo());
    }

    // 测试注销  ---- http://localhost:8081/acc/logout
    @GetMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }
    
    /**
     * sa-token 鉴权方式
     * 1-注解式鉴权（只对controller有效
     * 2-代码式鉴权（通用）
     * 3- AOP 鉴权（通用）
     * 4- 路径鉴权
     * */
    
    // ----- 注解式鉴权 ---

    // 登录认证：只有登录之后才能进入该方法 
    @GetMapping
    @SaCheckLogin
    public String info(){
        
        return "查询用户信息";
    }

    // 角色认证：必须具有指定角色才能进入该方法 
    @PostMapping("add")
    @SaCheckRole("super-admin")
    public String add(){
        return "角色认证";
    }

    // 权限认证：必须具有指定权限才能进入该方法 
    @SaCheckPermission("user-add")
    @RequestMapping("addByPermission")
    public String addByPermission() {
        return "权限认证";
    }

    // 二级认证：必须二级认证之后才能进入该方法 
    @SaCheckSafe()
    @RequestMapping("addTwoCheck")
    public String addTwoCheck() {
        return "二级认证";
    }

    // Http Basic 认证：只有通过 Basic 认证后才能进入该方法 
    @SaCheckBasic(account = "sa:123456")
    @RequestMapping("addHttpBasic")
    public String addHttpBasic() {
        return "Http Basic 认证：只有通过 Basic 认证后才能进入该方法 ";
    }
    
    
    @GetMapping("checkRoute")
    public String checkRoute(){
        return "ok";
    }
    
    // ---- session --- 
    
    @GetMapping("session")
    public void setSession(){
        SaSession session = StpUtil.getSession(true);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        
        session.set(tokenInfo.getLoginId().toString(),tokenInfo);
        log.error("session:{}",session.toString());
    }
    @GetMapping("getSession")
    public void getSession(){
        SaSession session = StpUtil.getSession(true);

      
        log.error("获取session:{}",session.toString());
    }
    @GetMapping("tokenSession")
    public void getTokenSession(){
        SaSession session = StpUtil.getTokenSession();
        log.error("tokenSession:{}",session.toString());
    }
    
    
    // -- 二级认证 
    
    /**前置条件 is-concurrent=true 以及 is-share: true */
    // todo 没通过
    @GetMapping("checkSafe")
    @SaCheckSafe
    public String SaCheckSafe(){
        StpUtil.openSafe(120);
        StpUtil.login(10001,DEVICE_PC);
        boolean safe = StpUtil.isSafe();
        log.error("当前会话是否处于二级认证时间内： {}",safe);
        StpUtil.closeSafe();
        return "二级认证";
    }
    
    
    
    
    
    
    


}
